import random
import re
from time import sleep

import openpyxl
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
'''
使用 python  和 selenium 读取excel 手机设备数据，爬取百度数据 
'''
# 文件路径
file_path = "D:\\workNote\\钉钉\\设备型号副本.xlsx"
output_file_path = "更新后的设备信息.xlsx"

# 定义查询函数，使用 Selenium 来进行请求
def query_device_info_baidu(device_model, driver):
    """
    通过百度搜索获取设备的上市和停售时间。
    """
    search_url = f"https://www.baidu.com/s?wd={device_model}+上市时间+停售时间"

    # # 配置 Chrome 无头浏览器（不显示浏览器窗口）
    # chrome_options = Options()
    # chrome_options.add_argument("--headless")  # 不弹出浏览器界面
    # chrome_options.add_argument("--disable-gpu")  # 禁用 GPU 加速
    # chrome_options.add_argument("--no-sandbox")  # 禁用沙盒模式
    # chrome_options.add_argument("-disable-dev-shm-usage")  # 降低内存使用
    # chrome_options.page_load_strategy = 'none'  # 不等待页面完全加载
    #
    # # 启动浏览器
    # driver = webdriver.Chrome(options=chrome_options)
    driver.get(search_url)
    # 等待元素加载（最大等待时间 10 秒）
    # WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "c-container")))

    # 等待页面加载
    sleep(random.uniform(2, 5))

    # 获取页面源码
    page_source = driver.page_source

    # 解析页面
    soup = BeautifulSoup(page_source, "html.parser")

    # 初始化上市时间和停售时间
    listing_time, discontinued_time = None, None

    # 解析百度搜索摘要
    result_divs = soup.find_all("div", class_="c-container")  # 搜索结果的主要容器
    for div in result_divs:
        # 提取标题和链接
        title = div.find("h3")
        link = div.find("a")
        p_tag = div.find("p", class_="md")

        # 提取标题或链接中的时间信息
        if title:
            text = title.get_text()
            if "上市" in text or "发布" in text:
                listing_time = extract_time_from_text(text, ["上市", "发布"])
            if "停售" in text or "停产" in text:
                discontinued_time = extract_time_from_text(text, ["停售", "停产"])

        if listing_time is None and p_tag:
            text = p_tag.get_text()
            if "上市" in text or "发布" in text:
                listing_time = extract_time_from_text(text, ["上市", "发布"])
            if "停售" in text or "停产" in text:
                discontinued_time = extract_time_from_text(text, ["停售", "停产"])

        # 提取正文内容
        if listing_time is None:
            content = div.get_text()
            if "上市" in content or "发布" in content:
                listing_time = extract_time_from_text(content, ["上市", "发布"])
            if "停售" in content or "停产" in content:
                discontinued_time = extract_time_from_text(content, ["停售", "停产"])

        # 如果两个时间都找到，提前结束
        if listing_time and discontinued_time:
            break

    return listing_time, discontinued_time


def extract_time_from_text(text, keywords):
    """
    从文本中提取时间信息，根据关键词过滤，并返回时间字符串。
    """
    # 匹配可能的时间格式
    time_patterns = [
        r"(\d{4}年\d{1,2}月\d{1,2}日)",  # 完整日期：2022年11月23日
        r"(\d{4}年\d{1,2}月)",  # 年月：2022年11月
        r"(\d{4}年)",  # 年份：2022年
    ]

    # 合成匹配的正则表达式
    keywords_pattern = "|".join(keywords)  # 将多个关键词用 "或" 连接

    # 在关键词之后查找时间
    for pattern in time_patterns:
        # 匹配关键词后出现的时间
        match = re.search(rf"({keywords_pattern}).*?({pattern})", text)
        if match:
            return match.group(2)  # 返回匹配的时间部分

    # 如果没有匹配到，尝试在关键词之前匹配时间
    for pattern in time_patterns:
        # 匹配时间前面可能有关键词
        match = re.search(rf"({pattern}).*?({keywords_pattern})", text)
        if match:
            return match.group(1)  # 返回匹配的时间部分

    return None



#  ----------------从这里开始---------------------------
# 读取 Excel 文件， 读取手机设备查询互联网的 上市和 停售信息
wb = openpyxl.load_workbook(file_path)
sheet = wb.active

user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36"
]
# 配置 Chrome 无头浏览器（不显示浏览器窗口）
chrome_options = Options()
# chrome_options.add_argument("--headless")  # 不弹出浏览器界面
chrome_options.add_argument("--disable-gpu")  # 禁用 GPU 加速
chrome_options.add_argument("--no-sandbox")  # 禁用沙盒模式
chrome_options.add_argument("-disable-dev-shm-usage")  # 降低内存使用
chrome_options.page_load_strategy = 'none'  # 不等待页面完全加载
# # 随机选择一个 User-Agent
# user_agent = random.choice(user_agents)
# chrome_options = Options()
# # 设置随机的 User-Agent
# chrome_options.add_argument(f"user-agent={user_agent}")

# 启动浏览器
driver = webdriver.Chrome(options=chrome_options)

# 遍历设备型号并补全信息
for row in sheet.iter_rows(min_row=2, max_row=sheet.max_row, min_col=1, max_col=3):
    model, listing_time, discontinued_time = row
    device_model = model.value

    # 仅查询空白的上市时间或停售时间
    if (listing_time.value is None or listing_time.value == "") or \
       (discontinued_time.value is None or discontinued_time.value == ""):
        print(f"查询设备: {device_model}")

        listing, discontinued = query_device_info_baidu(device_model, driver)

        # 更新上市和停售时间
        if listing_time.value is None or listing_time.value == "":
            listing_time.value = listing if listing else "未知"

        if discontinued_time.value is None or discontinued_time.value == "":
            discontinued_time.value = discontinued if discontinued else "未知"

        # 防止访问过快，随机休眠
        sleep(random.uniform(2, 5))

# 保存更新后的文件
wb.save(output_file_path)
print(f"更新完成，已保存到：{output_file_path}")
